/// <reference path="../classes.js" />
/// <reference path="QUnit/qunit-1.11.0.js" />

/*
This Test Class include
  Worker:
    Init
    fullName
    renderPartial
    renderFull
  Expert:
    Init
    fullName
    renderPartial
    renderFull
  Manager:
    Init
    fullName
    Adding Incorect Instanceof As Employee, should throw exception.
      Managers cannot manage other managers.
    Adding Incorect Instanceof As Employee, should throw exception
    renderPartial
    renderFull
  Building:
    Init - 3
    fullName
    renderPartial
    renderFull
  AdministrativeBuilding:
    Init - 3
    Add-Workers to AdministrativeBuilding and check there values
    Adding Incorect Instanceof As Workers, should throw exception
    renderPartial
    renderFull
  Branchh:
    Init
    Add Building
    Number of workers
    Number of machines
    Number of vehicles
    Can not add already added building
    Adding Incorect Instanceof As Building, should throw exception
    renderPartial
    renderFull
  Company:
    Init
    Adding branches
    Can not add already added building
    Adding Incorect Instanceof As Branches, should throw exception
    renderPartial
    renderFull

  TODO:
  Company:
    renderPartial
    renderFull
*/
(function () {

module("Worker");
{
  test("Init", function() {
    
    var firstName = "Marto", 
      lastName = "Marto2", 
      age = 24, 
      workExperience = 5;

    var worker = new Worker(firstName, lastName, age, workExperience);

    equal(worker.firstName, firstName, "First name - set");
    equal(worker.lastName, lastName, "Last name - set");
    equal(worker.age, age, "Age - set");
    equal(worker.workExperience, workExperience, "Work experience - set");
  });
  
  test("Full Name", function() {
    var firstName = "Marto", 
      lastName = "Marto2", 
      age = 9, 
      workExperience = 5;

    var worker = new Worker(firstName, lastName, age, workExperience);

    var expected = "" + worker.firstName + " " + worker.lastName;
    var actual =  worker.fullName();
    equal(expected, actual, "return fullName");
  });

  test("Render Partial", function () {
    var worker = new Worker("name1", "name2", 234,43);

    var fixture = document.getElementById("qunit-fixture");
    var container = worker.renderPartial();
    $(fixture).append(container);

    var expected = "<div id=\"qunit-fixture\"><div class=\"worker\">name1 name2</div></div>";
    equal(fixture.outerHTML, expected, "Render Partial");
  });

  test("Render Full", function () {
    var worker = new Worker("name1", "name2", 234,43);

    var fixture = document.getElementById("qunit-fixture");
    var container = worker.renderFull();
    $(fixture).append(container);

    var expected = "<div id=\"qunit-fixture\"><div class=\"worker-full\"><div class=\"name-visualisation\">name1 name2</div><div class=\"characteristics-visualisation\"> Age:234, work experience: 43</div></div></div>";
    equal(fixture.outerHTML, expected, "Render Full");
  });
}

module("Expert");
{
  test("Init", function() {
    
    var firstName = "Alex", 
      lastName = "Alex2", 
      age = 54, 
      workExperience = 21,
      degree = "Quantum mechanics";

    var expert = new Expert(firstName, lastName, age, workExperience, degree);

    equal(expert.firstName, firstName, "First Name - set");
    equal(expert.lastName, lastName, "Last name - set");
    equal(expert.age, age, "Age - set");
    equal(expert.workExperience, workExperience, "Work Experience - set");
    equal(expert.degree, degree, "Degree - set");
  });

  test("Full Name", function() {
    var firstName = "Alex", 
      lastName = "Alex2", 
      age = 54, 
      workExperience = 21,
      degree = "Quantum mechanics";

    var expert = new Expert(firstName, lastName, age, workExperience, degree);

    var expected = "" + expert.firstName + " " + expert.lastName;
    var actual =  expert.fullName();
    equal(expected, actual, "return fullName");
  });

  test("Render Partial", function () {
    var expert = new Expert("name2", "name23", 29, 3, "someExpert");

    var fixture = document.getElementById("qunit-fixture");
    var container = expert.renderPartial();
    $(fixture).append(container);

    var expected = "<div id=\"qunit-fixture\"><div class=\"worker expert\">name2 name23</div></div>";
    equal(fixture.outerHTML, expected, "Render Partial");
  });

  test("Render Full", function () {
    var expert = new Expert("name2", "name23", 29, 3, "someExpert");

    var fixture = document.getElementById("qunit-fixture");
    var container = expert.renderFull();
    $(fixture).append(container);

    var expected = "<div id=\"qunit-fixture\"><div class=\"worker-full expert-full\"><div class=\"name-visualisation\">name2 name23</div><div class=\"characteristics-visualisation\"> Age:29, work experience: 3</div><div class=\"degree-visualisation\"> Degree:someExpert</div></div></div>";
    equal(fixture.outerHTML, expected, "Render Full");
  });
}

module("Manager");
{
  test("Init", function() {
    var firstName = "Marto", 
      lastName = "Marto2", 
      age = 40, 
      workExperience = 8,
      degree = "Economics"

    var manager = new Manager(firstName, lastName, age, workExperience, degree);

    equal(manager.firstName, firstName, "First Name - set");
    equal(manager.lastName, lastName, "Last name - set");
    equal(manager.age, age, "Age - set");
    equal(manager.workExperience, workExperience, "Work Experience - set");
    equal(manager.degree, degree, "Degree - set");
  });

  test("Full Name", function() {
    var firstName = "Marto", 
      lastName = "Marto2", 
      age = 40, 
      workExperience = 8,
      degree = "Economics"

    var manager = new Manager(firstName, lastName, age, workExperience, degree);

    var expected = "" + manager.firstName + " " + manager.lastName;
    var actual =  manager.fullName();
    equal(expected, actual, "return fullName");
  });

  test("Add Employee", function() {
    var manager = new Manager("Marto", "Marto2", 40, 8, "Economics");

    manager.addManagedEmployee(new Worker("John", "Bon Jovi", 32, 12));
    equal(manager.workers.length, 1, "Added new Employee");

    manager.addManagedEmployee(new Expert("John2", "Bon Jovi2", 32, 12, "something"));
    equal(manager.workers.length, 2, "Added new Employee");

    manager.addManagedEmployee(new Worker("John2", "Bon Jovi2", 32, 12));
    equal(manager.workers.length, 3, "Added new Employee");
  });

  test("Add already added Employee", function() {
    var manager = new Manager("Marto", "Marto2", 40, 8, "Economics");
    var worker = new Worker("John", "Bon Jovi", 32, 12);

    manager.addManagedEmployee(worker);
    equal(manager.workers.length, 1, "Added new Employee");

    manager.addManagedEmployee(worker);
    equal(manager.workers.length, 1, "Added new Employee");

    manager.addManagedEmployee(worker);
    equal(manager.workers.length, 1, "Added new Employee");
  });

  test("Adding Incorect Instanceof As Employee, should throw exception. Managers cannot manage other managers.", function () {
    var manager = new Manager("Marto", "Marto2", 40, 8, "Economics");

    throws(function () {
          manager.addManagedEmployee(new Manager("name3", "name24", 29, 3, "someManager"));
      },"I'm Manager!!!  " + 
      "Managers cannot manage other managers.");

    equal(manager.workers.length, 0, "No invalid elements are added.");
  });

  test("Adding Incorect Instanceof As Employee, should throw exception", function () {
    var manager = new Manager("Marto", "Marto2", 40, 8, "Economics");

    throws(function () {
        manager.addManagedEmployee(new Building("name1", 45645, 456456, true, 5345345));
    },"I'm Building!!!  " + 
    "Only workers can be employees of the manager.");
    
    throws(function () {
        manager.addManagedEmployee(new AdministrativeBuilding("name2", 456545, 4564456, true, 53453345));
    },"I'm AdministrativeBuilding!!!  " + 
    "Only workers can be employees of the manager.");
    
    throws(function () {
        manager.addManagedEmployee(new ProductionBuilding("name3", 456245, 4562456, true, 53453453));
    },"I'm ProductionBuilding!!!  " + 
    "Only workers can be employees of the manager.");
    
    throws(function () {
        manager.addManagedEmployee(new Machine("Sofia", 15235));
    },"I'm Machine!!!  " + 
    "Only workers can be employees of the manager.");

    throws(function () {
        manager.addManagedEmployee(new Server(2008, 6, 3, 543, "Linux", "3535 Ram"));
    },"I'm Server!!!  " + 
    "Only workers can be employees of the manager.");

    throws(function () {
        manager.addManagedEmployee(new Vehicle(10, 3, 5, 8, "yes", "Van"));
    },"I'm Vehicle!!!  " + 
    "Only workers can be employees of the manager.");
    
    throws(function () {
        manager.addManagedEmployee(new Branch("Sofia", 15235));
    },"I'm Branch!!!  " + 
    "Only workers can be employees of the manager.");

    throws(function () {
        manager.addManagedEmployee(new Company("Kubrat", 3000000));
    },"I'm Company!!!  " + 
    "Only workers can be employees of the manager.");

    equal(manager.workers.length, 0, "No invalid elements are added.");
  });

  test("Render Partial", function () {
    var manager = new Manager("Marto", "Marto2", 40, 8, "Economics");

    var fixture = document.getElementById("qunit-fixture");
    var container = manager.renderPartial();
    $(fixture).append(container);

    var expected = "<div id=\"qunit-fixture\"><div class=\"worker expert manager\">Marto Marto2</div></div>";
    equal(fixture.outerHTML, expected, "Render Partial");
  });

  test("Render Full", function () {
    var manager = new Manager("Marto", "Marto2", 40, 8, "Economics");

    var fixture = document.getElementById("qunit-fixture");
    var container = manager.renderFull();
    $(fixture).append(container);

    var expected = "<div id=\"qunit-fixture\"><div class=\"worker-full expert-full manager-full\"><div class=\"name-visualisation\">Marto Marto2</div><div class=\"characteristics-visualisation\"> Age:40, work experience: 8</div><div class=\"degree-visualisation\"> Degree:Economics</div><div> Number of managed employees: 0</div></div></div>";
    equal(fixture.outerHTML, expected, "Render Full");
  });

  test("Render Partial + worker", function () {
    var manager = new Manager("Marto", "Marto2", 40, 8, "Economics");
    var worker = new Worker("John", "Bon Jovi", 32, 12);
    manager.addManagedEmployee(worker);

    var fixture = document.getElementById("qunit-fixture");
    var container = manager.renderPartial();
    $(fixture).append(container);

    var expected = "<div id=\"qunit-fixture\"><div class=\"worker expert manager\">Marto Marto2</div></div>";
    equal(fixture.outerHTML, expected, "Render Partial");
  });

  test("Render Full + worker", function () {
    var manager = new Manager("Marto", "Marto2", 40, 8, "Economics");
    var worker = new Worker("John", "Bon Jovi", 32, 12);
    manager.addManagedEmployee(worker);

    var fixture = document.getElementById("qunit-fixture");
    var container = manager.renderFull();
    $(fixture).append(container);

    var expected = "<div id=\"qunit-fixture\"><div class=\"worker-full expert-full manager-full\"><div class=\"name-visualisation\">Marto Marto2</div><div class=\"characteristics-visualisation\"> Age:40, work experience: 8</div><div class=\"degree-visualisation\"> Degree:Economics</div><div> Number of managed employees: 1</div></div></div>";
    equal(fixture.outerHTML, expected, "Render Full");
  });

  test("Render Full + worker, expert expert", function () {
    var manager = new Manager("Marto", "Marto2", 40, 8, "Economics");
    manager.addManagedEmployee(new Worker("John", "Bon Jovi", 32, 12));
    manager.addManagedEmployee(new Expert("John2", "Bon Jovi", 32, 12, "asdasda"));
    manager.addManagedEmployee(new Expert("John3", "Bon Jovi", 32, 12, "asdasdas"));


    var fixture = document.getElementById("qunit-fixture");
    var container = manager.renderFull();
    $(fixture).append(container);

    var expected = "<div id=\"qunit-fixture\"><div class=\"worker-full expert-full manager-full\"><div class=\"name-visualisation\">Marto Marto2</div><div class=\"characteristics-visualisation\"> Age:40, work experience: 8</div><div class=\"degree-visualisation\"> Degree:Economics</div><div> Number of managed employees: 3</div></div></div>";
    equal(fixture.outerHTML, expected, "Render Full");
  });
}

module("Building");
{
  test("Init - Full true", function() {
    var name ="Production building",
      area = 350,
      retailPrice = 1000000,
      rented = true, 
      yearlyRent = 1000000;

    var building = new ProductionBuilding(name, area, retailPrice, rented, yearlyRent);

    equal(building.name, name, "Name - set");
    equal(building.area, area, "Area - set");
    equal(building.retailPrice, retailPrice, "Retail Price - set");
    equal(building.rented, rented, "Rented - set");
    equal(building.yearlyRent, yearlyRent, "Yearly rent - set");
  });

  test("Init - Full false", function() {
    var name ="Production building",
      area = 350,
      retailPrice = 1000000,
      rented = false,
      expexctedYearlyRent = "N/a";

    var building = new ProductionBuilding(name, area, retailPrice, rented);

    equal(building.name, name, "Naame - set");
    equal(building.area, area, "Area - set");
    equal(building.retailPrice, retailPrice, "Retail Price - set");
    equal(building.rented, rented, "Rented - set");
    equal(building.yearlyRent, expexctedYearlyRent, "Yearly rent - set (N/a)");
  });

  test("Init - Full false (with input \"yearlyRent\") ", function() {
    var name ="Production building",
      area = 350,
      retailPrice = 1000000,
      rented = false, 
      yearlyRent = 1000000,
      expexctedYearlyRent = "N/a";

    var building = new ProductionBuilding(name, area, retailPrice, rented, yearlyRent);

    equal(building.name, name, "Name - set");
    equal(building.area, area, "Area - set");
    equal(building.retailPrice, retailPrice, "Retail Price - set");
    equal(building.rented, rented, "Rented - set");
    equal(building.yearlyRent, expexctedYearlyRent, "Yearly rent - set (N/a)");
  });

  test("Render Partial", function () {
    var building = new ProductionBuilding("Production building", 350, 1000000, true, 1000000);

    var fixture = document.getElementById("qunit-fixture");
    var container = building.renderPartial();
    $(fixture).append(container);

    var expected = "<div id=\"qunit-fixture\"><div class=\"building administrative production\"><div class=\"buildingName\">Building name: Production building</div></div></div>";
    equal(fixture.outerHTML, expected, "Render Partial");
  });

  test("Render Full", function () {
    var building = new ProductionBuilding("Production building", 350, 1000000, true, 1000000);

    var fixture = document.getElementById("qunit-fixture");
    var container = building.renderFull();
    $(fixture).append(container);

    var expected = "<div id=\"qunit-fixture\"><div class=\"building-full administrative-full ui-sortable production-full\"><div class=\"building-name\">Building name: Production building</div><div>Area of building: Production building square meters.</div><div>Retail price:Production building leva</div><div>Building rented for 1000000 leva per year.</div><div class=\"number-container-workers\">Number of employees in building: 0</div><div class=\"number-container-machines\">Number of machines in building: 0</div><div class=\"number-container-vehicles\">Number of vehicles in building: 0</div></div></div>";
    equal(fixture.outerHTML, expected, "Render Full");
  });
}

module("AdministrativeBuilding");
{
  test("Init - Full true", function() {
    var name ="Plovdiv admin",
      area = 2000,
      retailPrice = 3000000,
      rented = true, 
      yearlyRent = 1000000;

    var aBuilding = new ProductionBuilding(name, area, retailPrice, rented, yearlyRent);

    equal(name, aBuilding.name, "Name - set");
    equal(area, aBuilding.area, "Area - set");
    equal(retailPrice, aBuilding.retailPrice, "Retail Price - set");
    equal(rented, aBuilding.rented, "Rented - set");
    equal(yearlyRent, aBuilding.yearlyRent, "Yearly rent - set");
  });

  test("Init - Full false", function() {
    var name ="Plovdiv admin",
      area = 2000,
      retailPrice = 3000000,
      rented = false,
      expexctedYearlyRent = "N/a";
      
    var aBuilding = new ProductionBuilding(name, area, retailPrice, rented);

    equal(name, aBuilding.name, "Naame - set");
    equal(area, aBuilding.area, "Area - set");
    equal(retailPrice, aBuilding.retailPrice, "Retail Price - set");
    equal(rented, aBuilding.rented, "Rented - set");
    equal(expexctedYearlyRent, aBuilding.yearlyRent, "Yearly rent - set (N/a)");
  });

  test("Init - Full false (with input \"yearlyRent\") ", function() {
    var name ="Plovdiv admin",
      area = 2000,
      retailPrice = 3000000,
      rented = false, 
      yearlyRent = 1000000,
      expexctedYearlyRent = "N/a";

    var aBuilding = new ProductionBuilding(name, area, retailPrice, rented, yearlyRent);

    equal(name, aBuilding.name, "Name - set");
    equal(area, aBuilding.area, "Area - set");
    equal(retailPrice, aBuilding.retailPrice, "Retail Price - set");
    equal(rented, aBuilding.rented, "Rented - set");
    equal(expexctedYearlyRent, aBuilding.yearlyRent, "Yearly rent - set (N/a)");
  });

  test("Add-Workers to AdministrativeBuilding and check there values", function() {
    var building = new AdministrativeBuilding("First admin", 20000, 3000000, true, 100000);
    
    building.addWorker(new Worker("John", "Bon Jovi", 32, 12));
    equal(building.workers.length, 1, "(1) - added 1st Worker");
    equal("John", building.workers[building.workers.length - 1].firstName, "First name - set");
    equal("Bon Jovi", building.workers[building.workers.length - 1].lastName, "Secont name - set");
    equal(32, building.workers[building.workers.length - 1].age, "Age - set");
    equal(12, building.workers[building.workers.length - 1].workExperience, "Work experience - set");

    building.addWorker(new Worker("Clint", "Eastwood", 70, 48));
    equal(building.workers.length, 2, "(2) - added 2nd Worker");
    equal("Clint", building.workers[building.workers.length - 1].firstName, "First name - set");
    equal("Eastwood", building.workers[building.workers.length - 1].lastName, "Secont name - set");
    equal(70, building.workers[building.workers.length - 1].age, "Age - set");
    equal(48, building.workers[building.workers.length - 1].workExperience, "Work experience - set");

    building.addWorker(new Expert("Asen", "Eastwood", 70, 48, "Physical education"));
    equal(building.workers.length, 3, "(3) - added 1nd Expert");
    equal("Asen", building.workers[building.workers.length - 1].firstName, "First name - set");
    equal(building.workers[building.workers.length - 1].lastName, "Eastwood", "Secont name - set");
    equal(70, building.workers[building.workers.length - 1].age, "Age - set");
    equal(48, building.workers[building.workers.length - 1].workExperience, "Work experience - set");
    equal("Physical education", building.workers[building.workers.length - 1].degree, "Work experience - set");

    building.addWorker(new Manager("Petar", "Petrov", 30, 8, "Economics"));
    equal(building.workers.length, 4, "(4) - added 1nd Manager");
    equal("Petar", building.workers[building.workers.length - 1].firstName, "First name - set");
    equal("Petrov", building.workers[building.workers.length - 1].lastName, "Secont name - set");
    equal(30, building.workers[building.workers.length - 1].age, "Age - set");
    equal(8, building.workers[building.workers.length - 1].workExperience, "Work experience - set");
    equal("Economics", building.workers[building.workers.length - 1].degree, "Work experience - set");

    building.addWorker(new Expert("Regeb", "Evedik", 40, 26, "Quantum mechanics"));
    equal(building.workers.length, 5, "(5) - added 1nd Expert");
    equal("Regeb", building.workers[building.workers.length - 1].firstName, "First name - set");
    equal("Evedik", building.workers[building.workers.length - 1].lastName, "Secont name - set");
    equal(40, building.workers[building.workers.length - 1].age, "Age - set");
    equal(26, building.workers[building.workers.length - 1].workExperience, "Work experience - set");
    equal("Quantum mechanics", building.workers[building.workers.length - 1].degree, "Work experience - set");
  });

  test("Adding Incorect Instanceof As Workers, should throw exception", function () {
    var aBuilding = new AdministrativeBuilding("Sofia", 15235);
    
    throws(function () {
        aBuilding.addWorker(new Building("name1", 45645, 456456, true, 5345345));
    },"I'm Building!!!  " + 
    "Only workers can populate buildings.");
    
    throws(function () {
        aBuilding.addWorker(new AdministrativeBuilding("name2", 456545, 4564456, true, 53453345));
    },"I'm AdministrativeBuilding!!!  " + 
    "Only workers can populate buildings.");
    
    throws(function () {
        aBuilding.addWorker(new ProductionBuilding("name3", 456245, 4562456, true, 53453453));
    },"I'm ProductionBuilding!!!  " + 
    "Only workers can populate buildings.");
    
    throws(function () {
        aBuilding.addWorker(new Machine("Sofia", 15235));
    },"I'm Machine!!!  " + 
    "Only workers can populate buildings.");

    throws(function () {
        aBuilding.addWorker(new Server(2008, 6, 3, 543, "Linux", "3535 Ram"));
    },"I'm Server!!!  " + 
    "Only workers can populate buildings.");

    throws(function () {
        aBuilding.addWorker(new Vehicle(10, 3, 5, 8, "yes", "Van"));
    },"I'm Vehicle!!!  " + 
    "Only workers can populate buildings.");
    
    throws(function () {
        aBuilding.addWorker(new Branch("Sofia", 15235));
    },"I'm Branch!!!  " + 
    "Only workers can populate buildings.");

    throws(function () {
        aBuilding.addWorker(new Company("Kubrat", 3000000));
    },"I'm Company!!!  " + 
    "Only workers can populate buildings.");

    equal(aBuilding.workers.length, 0, "No invalid elements are added.");
  });
  
  test("Render Partial", function () {
    var building = new AdministrativeBuilding("First admin", 20000, 3000000, true, 100000);
    
    building.addWorker(new Worker("John", "Bon Jovi", 32, 12));
    building.addWorker(new Worker("Clint", "Eastwood", 70, 48));
    building.addWorker(new Expert("Asen", "Eastwood", 70, 48, "Physical education"));
    building.addWorker(new Manager("Petar", "Petrov", 30, 8, "Economics"));
    building.addWorker(new Expert("Regeb", "Evedik", 40, 26, "Quantum mechanics"));

    var fixture = document.getElementById("qunit-fixture");
    var container = building.renderPartial();
    $(fixture).append(container);

    var expected = "<div id=\"qunit-fixture\"><div class=\"building administrative\"><div class=\"buildingName\">Building name: First admin</div><ul class=\"list-of-workers ui-sortable\"><div class=\"worker\">John Bon Jovi</div><div class=\"worker\">Clint Eastwood</div><div class=\"worker expert\">Asen Eastwood</div><div class=\"worker expert manager\">Petar Petrov</div><div class=\"worker expert\">Regeb Evedik</div></ul></div></div>";
    equal(fixture.outerHTML, expected, "Render Partial");
  });

  test("Render Full", function () {
    var building = new AdministrativeBuilding("First admin", 20000, 3000000, true, 100000);
    
    building.addWorker(new Worker("John", "Bon Jovi", 32, 12));
    building.addWorker(new Worker("Clint", "Eastwood", 70, 48));
    building.addWorker(new Expert("Asen", "Eastwood", 70, 48, "Physical education"));
    building.addWorker(new Manager("Petar", "Petrov", 30, 8, "Economics"));
    building.addWorker(new Expert("Regeb", "Evedik", 40, 26, "Quantum mechanics"));

    var fixture = document.getElementById("qunit-fixture");
    var container = building.renderFull();
    $(fixture).append(container);

    var expected = "<div id=\"qunit-fixture\"><div class=\"building-full administrative-full ui-sortable\"><div class=\"building-name\">Building name: First admin</div><div>Area of building: First admin square meters.</div><div>Retail price:First admin leva</div><div>Building rented for 100000 leva per year.</div><div class=\"number-container-workers\">Number of employees in building: 5</div></div></div>";
    equal(fixture.outerHTML, expected, "Render Full");
  });
}

module("Branch");
{
  test("Init", function() {
    var town  ="Sofia",
      numberOfPotentialClients = 15235;

    var branch = new Branch(town, numberOfPotentialClients);

    equal(town, branch.town, "Town - set");
    equal(numberOfPotentialClients, branch.numberOfPotentialClients, "Number of potential clients - set");
  });

  test("Add Building", function() {
      var branch = new Branch("Sofia", 15235);

      branch.addBuilding(new Building("name1", 45645, 456456, true, 5345345));
      equal(branch.buildings.length, 1, "Add new Building - set");
      
      branch.addBuilding(new AdministrativeBuilding("name2", 456545, 4564456, true, 53453345));
      equal(branch.buildings.length, 2, "Add new AdministrativeBuilding - set");
      
      branch.addBuilding(new ProductionBuilding("name3", 456245, 4562456, true, 53453453));
      equal(branch.buildings.length, 3, "Add new ProductionBuilding - set");
  });

  test("Can not add already added building", function () {
    var branch = new Branch("Sofia", 15235);

    var aBuilding = new AdministrativeBuilding("First admin", 20000, 3000000, true, 100000);
    for (var i = 4; i >= 0; i--) {
      branch.addBuilding(aBuilding);
      equal(branch.buildings.length, 1, "The same building can not be add again.");
    }

    var building = new AdministrativeBuilding("building", 20000, 3000000, true, 100000);
    for (var i = 4; i >= 0; i--) {
      branch.addBuilding(building);
      equal(branch.buildings.length, 2, "The same building can not be add again.");
    }
  });

  test("Number of workers", function() {
      var branch = new Branch("Sofia", 15235);

      var aBuilding1 = new AdministrativeBuilding("First admin", 20000, 3000000, true, 100000);
      var aBuilding2 = new AdministrativeBuilding("First admin2", 20000, 3000000, true, 100000);

      for (var i = 9; i >= 0; i--) {
        aBuilding1.addWorker(new Worker("John", "Bon Jovi", 32, 12));
        aBuilding1.addWorker(new Worker("Clint", "Eastwood", 70, 48));
        aBuilding1.addWorker(new Expert("Asen", "Eastwood", 70, 48, "Physical education"));
        aBuilding1.addWorker(new Manager("Petar", "Petrov", 30, 8, "Economics"));
        aBuilding1.addWorker(new Expert("Regeb", "Evedik", 40, 26, "Quantum mechanics"));
      }
      var workersCount1 = aBuilding1.workers.length;

      for (var i = 9; i >= 0; i--) {
        aBuilding2.addWorker(new Worker("John", "Bon Jovi", 32, 12));
        aBuilding2.addWorker(new Worker("Clint", "Eastwood", 70, 48));
        aBuilding2.addWorker(new Expert("Asen", "Eastwood", 70, 48, "Physical education"));
        aBuilding2.addWorker(new Manager("Petar", "Petrov", 30, 8, "Economics"));
        aBuilding2.addWorker(new Expert("Regeb", "Evedik", 40, 26, "Quantum mechanics"));
      }
      var workersCount2 = aBuilding2.workers.length;

      {
        branch.addBuilding(aBuilding1);
        equal(branch.buildings.length, 1, "Add new 1st Administrative Building whit workers");

        var expectedCount = workersCount1;
        equal(branch.numberOfWorkers(), expectedCount, "Number of workers - with 1 Administrative Building");
        

        branch.addBuilding(aBuilding2);      
        equal(branch.buildings.length, 2, "Add new 2nd Administrative Building with workers");

        var expectedCount = workersCount1 + workersCount2;
        equal(branch.numberOfWorkers(), expectedCount, "Number of workers - with 2 Administrative Building");
      }
  });

  test("Number of machines", function() {
      var branch = new Branch("Sofia", 15235);

      var pBuilding1 = new ProductionBuilding("First admin", 20000, 3000000, true, 100000);
      var pBuilding2 = new ProductionBuilding("First admin2", 20000, 3000000, true, 100000);

      for (var i = 9; i >= 0; i--) {
        pBuilding1.addMachine(new Machine(1990, 5, 25));
        pBuilding1.addMachine(new Machine(1999, 2, 21));
        pBuilding1.addMachine(new Machine(1998, 3, 10));
        pBuilding1.addMachine(new Machine(1997, 6, 25));
        pBuilding1.addMachine(new Machine(2008, 7, 20));
      }
      var machinesCount1 = pBuilding1.machines.length;

      for (var i = 19; i >= 0; i--) {
        pBuilding2.addMachine(new Machine(1990, 5, 25));
        pBuilding2.addMachine(new Machine(1999, 2, 21));
        pBuilding2.addMachine(new Machine(1998, 3, 10));
        pBuilding2.addMachine(new Machine(1997, 6, 25));
        pBuilding2.addMachine(new Machine(2008, 7, 20));
      }
      var machinesCount2 = pBuilding2.machines.length;

      {
        branch.addBuilding(pBuilding1);
        equal(branch.buildings.length, 1, "Add new 1st Production Building achines");

        var expectedCount = machinesCount1;
        equal(branch.numberOfMachines(), expectedCount, "Number of machines - with 1 Administrative Building");
        

        branch.addBuilding(pBuilding2);      
        equal(branch.buildings.length, 2, "Add new 2nd Production Building with achines");

        var expectedCount2 = machinesCount1 + machinesCount2;
        equal(branch.numberOfMachines(), expectedCount2, "Number of machines - with 2 Administrative Building");
      }
  });

  test("Number of vehicles", function() {
      var branch = new Branch("Sofia", 15235);

      var pBuilding1 = new ProductionBuilding("First admin", 20000, 3000000, true, 100000);
      var pBuilding2 = new ProductionBuilding("First admin2", 20000, 3000000, true, 100000);

      for (var i = 9; i >= 0; i--) {
        pBuilding1.addVehicle(new Vehicle(1990, 5, 25, 39943, false, "Car"));
        pBuilding1.addVehicle(new Vehicle(1999, 2, 21, 39943, false, "Car"));
        pBuilding1.addVehicle(new Vehicle(1998, 3, 10, 39943, false, "Car"));
        pBuilding1.addVehicle(new Vehicle(1997, 6, 25, 39943, false, "Car"));
        pBuilding1.addVehicle(new Vehicle(2008, 7, 20, 39943, false, "Car"));
      }
      var vehiclesCount1 = pBuilding1.vehicles.length;

      for (var i = 19; i >= 0; i--) {
        pBuilding2.addVehicle(new Vehicle(1990, 5, 25, 54545, false, "Car"));
        pBuilding2.addVehicle(new Vehicle(1999, 2, 21, 33543, false, "Car"));
        pBuilding2.addVehicle(new Vehicle(1998, 3, 10, 341443, false, "Car"));
        pBuilding2.addVehicle(new Vehicle(1997, 6, 25, 39943, false, "Car"));
        pBuilding2.addVehicle(new Vehicle(2008, 7, 20, 64377, false, "Car"));
      }
      var vehiclesCount2 = pBuilding2.vehicles.length;

      {
        branch.addBuilding(pBuilding1);
        equal(branch.buildings.length, 1, "Add new 1st Production Building with vehicles");

        var expectedCount = vehiclesCount1;
        equal(branch.numberOfVehicles(), expectedCount, "Number of vehicles - with 1 Administrative Building");


        branch.addBuilding(pBuilding2);      
        equal(branch.buildings.length, 2, "Add new 2nd Production Building with vehicles");

        var expectedCount2 = vehiclesCount1 + vehiclesCount2;
        equal(branch.numberOfVehicles(), expectedCount2, "Number of vehicles - with 2 Administrative Building");
      }
  });

  test("Adding Incorect Instanceof As Building, should throw exception", function () {
    var branch = new Branch("Sofia", 15235);

    throws(function () {
        branch.addBuilding(new Worker("name1", "name22", 29, 3));
    },"I'm Worker!!!  " + 
    "Only buildings can be added to branches.");

    throws(function () {
        branch.addBuilding(new Expert("name2", "name23", 29, 3, "someExpert"));
    },"I'm Expert!!!  " + 
    "Only buildings can be added to branches.");

    throws(function () {
        branch.addBuilding(new Manager("name3", "name24", 29, 3, "someManager"));
    },"I'm Manager!!!  " + 
    "Only buildings can be added to branches.");
    
    throws(function () {
        branch.addBuilding(new Machine("Sofia", 15235));
    },"I'm Machine!!!  " + 
    "Only buildings can be added to branches.");

    throws(function () {
        branch.addBuilding(new Server(2008, 6, 3, 543, "Linux", "3535 Ram"));
    },"I'm Server!!!  " + 
    "Only buildings can be added to branches.");

    throws(function () {
        branch.addBuilding(new Vehicle(10, 3, 5, 8, "yes", "Van"));
    },"I'm Vehicle!!!  " + 
    "Only buildings can be added to branches.");
    
    throws(function () {
        branch.addBuilding(new Branch("Sofia", 15235));
    },"I'm Branch!!!  " + 
    "Only buildings can be added to branches.");

    throws(function () {
        branch.addBuilding(new Company("Kubrat", 3000000));
    },"I'm Company!!!  " + 
    "Only buildings can be added to branches.");

    equal(branch.buildings.length, 0, "No invalid elements are added.");
  });
  
  test("Render Partial", function () {
    var branch = new Branch("Sofia", 15235);
    var pBuilding1 = new ProductionBuilding("First admin", 20000, 3000000, true, 100000);
    var pBuilding2 = new ProductionBuilding("First admin2", 20000, 3000000, true, 100000);
    var aBuilding1 = new AdministrativeBuilding("First admin", 20000, 3000000, true, 100000);
    var aBuilding2 = new AdministrativeBuilding("First admin2", 20000, 3000000, true, 100000);

    for (var i = 9; i >= 0; i--) {
      pBuilding1.addMachine(new Machine(1990, 5, 25));
      pBuilding1.addVehicle(new Vehicle(1998, 3, 10, 39943, false, "Car"));
    }
    for (var i = 19; i >= 0; i--) {
      pBuilding2.addMachine(new Machine(1998, 3, 10));
      pBuilding2.addVehicle(new Vehicle(1997, 6, 25, 39943, false, "Car"));
      pBuilding2.addVehicle(new Vehicle(2008, 7, 20, 64377, false, "Car"));
    }
    for (var i = 9; i >= 0; i--) {
      aBuilding1.addWorker(new Worker("John", "Bon Jovi", 32, 12));
      aBuilding1.addWorker(new Worker("Clint", "Eastwood", 70, 48));
    }
    for (var i = 9; i >= 0; i--) {
      aBuilding2.addWorker(new Manager("Petar", "Petrov", 30, 8, "Economics"));
      aBuilding2.addWorker(new Expert("Regeb", "Evedik", 40, 26, "Quantum mechanics"));
    }
    branch.addBuilding(pBuilding1);
    branch.addBuilding(aBuilding1);
    branch.addBuilding(pBuilding2);
    branch.addBuilding(aBuilding1);

    var fixture = document.getElementById("qunit-fixture");
    var container = branch.renderPartial();
    $(fixture).append(container);

    var expected = "<div id=\"qunit-fixture\"><div class=\"branch\"><div class=\"branchName\">Branch: Sofia</div><ul class=\"list-of-buildings ui-sortable\"><div class=\"building administrative production\"><div class=\"buildingName\">Building name: First admin</div><ul class=\"list-of-machines ui-sortable\"><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div></ul><ul class=\"list-of-vehicles ui-sortable\"><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div></ul></div><div class=\"building administrative\"><div class=\"buildingName\">Building name: First admin</div><ul class=\"list-of-workers ui-sortable\"><div class=\"worker\">John Bon Jovi</div><div class=\"worker\">Clint Eastwood</div><div class=\"worker\">John Bon Jovi</div><div class=\"worker\">Clint Eastwood</div><div class=\"worker\">John Bon Jovi</div><div class=\"worker\">Clint Eastwood</div><div class=\"worker\">John Bon Jovi</div><div class=\"worker\">Clint Eastwood</div><div class=\"worker\">John Bon Jovi</div><div class=\"worker\">Clint Eastwood</div><div class=\"worker\">John Bon Jovi</div><div class=\"worker\">Clint Eastwood</div><div class=\"worker\">John Bon Jovi</div><div class=\"worker\">Clint Eastwood</div><div class=\"worker\">John Bon Jovi</div><div class=\"worker\">Clint Eastwood</div><div class=\"worker\">John Bon Jovi</div><div class=\"worker\">Clint Eastwood</div><div class=\"worker\">John Bon Jovi</div><div class=\"worker\">Clint Eastwood</div></ul></div><div class=\"building administrative production\"><div class=\"buildingName\">Building name: First admin2</div><ul class=\"list-of-machines ui-sortable\"><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div><div class=\"machine\">Production machine</div></ul><ul class=\"list-of-vehicles ui-sortable\"><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div><div class=\"vehicle\">Vehicle</div></ul></div></ul></div></div>";
    equal(fixture.outerHTML, expected, "Render Partial");
  });

  test("Render Full", function () {
    var branch = new Branch("Sofia", 15235);
    var pBuilding1 = new ProductionBuilding("First admin", 20000, 3000000, true, 100000);
    var pBuilding2 = new ProductionBuilding("First admin2", 20000, 3000000, true, 100000);
    var aBuilding1 = new AdministrativeBuilding("First admin", 20000, 3000000, true, 100000);
    var aBuilding2 = new AdministrativeBuilding("First admin2", 20000, 3000000, true, 100000);

    for (var i = 9; i >= 0; i--) {
      pBuilding1.addMachine(new Machine(1990, 5, 25));
      pBuilding1.addVehicle(new Vehicle(1998, 3, 10, 39943, false, "Car"));
    }
    for (var i = 19; i >= 0; i--) {
      pBuilding2.addMachine(new Machine(1998, 3, 10));
      pBuilding2.addVehicle(new Vehicle(1997, 6, 25, 39943, false, "Car"));
      pBuilding2.addVehicle(new Vehicle(2008, 7, 20, 64377, false, "Car"));
    }
    for (var i = 9; i >= 0; i--) {
      aBuilding1.addWorker(new Worker("John", "Bon Jovi", 32, 12));
      aBuilding1.addWorker(new Worker("Clint", "Eastwood", 70, 48));
    }
    for (var i = 9; i >= 0; i--) {
      aBuilding2.addWorker(new Manager("Petar", "Petrov", 30, 8, "Economics"));
      aBuilding2.addWorker(new Expert("Regeb", "Evedik", 40, 26, "Quantum mechanics"));
    }
    branch.addBuilding(pBuilding1);
    branch.addBuilding(aBuilding1);
    branch.addBuilding(pBuilding2);
    branch.addBuilding(aBuilding1);

    var fixture = document.getElementById("qunit-fixture");
    var container = branch.renderFull();
    $(fixture).append(container);

    var expected = "<div id=\"qunit-fixture\"><div class=\"branch-full\"><div class=\"branch-name\">Branch town: Sofia</div><div>Potential clients: 15235</div><div class=\"number-container-buildings\">Number of buildings: 3</div><div class=\"number-container-workers\">Number of workers:20</div><div class=\"number-container-machines number-container-vehicles\">Number of machines:30</div><div>Number of vehicles:50</div></div></div>";
    equal(fixture.outerHTML, expected, "Render Full");
  });
}

module("Company");
{
  test("Init", function() {
    var name ="My own company name",
      value = 15235;

    var company = new Company(name, value);

    equal(name, company.name, "Name - set");
    equal(value, company.value, "Value - set");
    equal(company.branches.length, 0, "Number of buildings - 0");
    equal(company.numberOfWorkers(), 0, "Numbers of workers is 0");
  });

  test("Adding branches", function() {
    var company = new Company("My own company name", 15235);
    var branch = new Branch("Sofia", 15235);

    var building = new AdministrativeBuilding("First admin", 20000, 3000000, true, 100000);
    building.addWorker(new Worker("name", "name2", 66, 3));

    branch.addBuilding(building);

    company.addBranch(branch);
    equal(1, company.branches.length, "Added new branch.");

    equal(1, company.numberOfWorkers(), "Added company with 1 worker")
    
    company.addBranch(branch);
    equal(1, company.branches.length, "Can not add the already added branch.");
    
    equal(1, company.numberOfWorkers(), "Recheck: company with 1 worker")
  });

  test("Can not add already added building", function () {
    var company = new Company("My own company name", 15235);
    var branch1 = new Branch("Sofia", 15235);
    var branch2 = new Branch("Sofia", 15235);

    company.addBranch(branch1);
    equal(1, company.branches.length, "Added new branch.");
    for (var i = 4; i >= 0; i--) {
      company.addBranch(branch1);
      equal(company.branches.length, 1, "The same branch can not be add again.");
    }

    company.addBranch(branch2);
    equal(2, company.branches.length, "Added new branch.");
    for (var i = 4; i >= 0; i--) {
      company.addBranch(branch2);
      equal(company.branches.length, 2, "The same branch can not be add again.");
    }
  });

  test("Adding Incorect Instanceof As Branches, should throw exception", function () {
    var company = new Company("Sofia", 15235);

    throws(function () {
        company.addBranch(new Worker("name1", "name22", 29, 3));
    },"I'm Worker!!!  " + 
    "Only branches can be added to companies.");

    throws(function () {
        company.addBranch(new Expert("name2", "name23", 29, 3, "someExpert"));
    },"I'm Expert!!!  " + 
    "Only branches can be added to companies.");

    throws(function () {
        company.addBranch(new Manager("name3", "name24", 29, 3, "someManager"));
    },"I'm Manager!!!  " + 
    "Only branches can be added to companies.");
    
    throws(function () {
        company.addBranch(new Building("name1", 45645, 456456, true, 5345345));
    },"I'm Building!!!  " + 
    "Only branches can be added to companies.");
    
    throws(function () {
        company.addBranch(new AdministrativeBuilding("name2", 456545, 4564456, true, 53453345));
    },"I'm AdministrativeBuilding!!!  " + 
    "Only branches can be added to companies.");
    
    throws(function () {
        company.addBranch(new ProductionBuilding("name3", 456245, 4562456, true, 53453453));
    },"I'm ProductionBuilding!!!  " + 
    "Only branches can be added to companies.");
    
    throws(function () {
        company.addBranch(new Machine("Sofia", 15235));
    },"I'm Machine!!!  " + 
    "Only branches can be added to companies.");

    throws(function () {
        company.addBranch(new Server(2008, 6, 3, 543, "Linux", "3535 Ram"));
    },"I'm Server!!!  " + 
    "Only branches can be added to companies.");

    throws(function () {
        company.addBranch(new Vehicle(10, 3, 5, 8, "yes", "Van"));
    },"I'm Worker!!!  " + 
    "Only branches can be added to companies.");
    
    throws(function () {
        company.addBranch(new Company("Kubrat", 3000000));
    },"I'm Company!!!  " + 
    "Only branches can be added to companies.");

    equal(company.branches.length, 0, "No invalid elements are added.");
  });
}
}());
